◆ Java アプレット用 擬似スプライトマネージャ version 0.40

(c)1996-2000 Isawo-Kikuchi
◇ アーカイブ
 このアーカイブには、以下のファイルが含まれています。

SpriteLib.jarスプライトライブラリアーカイブ
SpriteManager.htmlこのファイル
ShootSaucer.javaデモゲーム ShootSaucer ソース
ShootSaucer.classデモゲーム ShootSaucer 本体
ShootSaucer.htmlデモゲーム ShootSaucer HTML
image/ShootSaucer 用イメージデータ
audio/ShootSaucer 用オーディオデータ
scroll.javaバックグラウンドサンプル scroll ソース
scroll.classバックグラウンドサンプル scroll 本体
scroll.htmlバックグラウンドサンプル scroll HTML
scroll/scroll 用イメージデータ

◇ 機能
 Java で、擬似的にスプライトを実現できます。パターンサイズやパターン数、プレーン数に制限はありません。プレーン番号が小さいものほど手前に表示されます。矩形以外のパターンを表示させたい場合は、透明化 GIFを使用してください。
 球面スクロールするバックグラウンドをサポートしています。バックグラウンド サイズ、プレーン数に制限はありません。バックグラウンドプレーン番号が小さいも のほど手前に表示されますが、任意のスプライトプレーン対任意のバックグラウンド プレーンのプライオリティ設定ができます。

◇ 解凍時の注意
 ロングファイルネームに対応した解凍ツールで展開してください。

◇ インターフェース
・SpriteControl クラス
 キャンバスを使わずに、直接アプレットに描画する時に使用します。ユーザーメソッドは以下の通り。

コンストラクタ
SpriteControl();
SpriteControl( pattern, plane, width, height, component );
	int pattern;	// パターン確保数
	int plane;	// プレーン確保数
	int width;	// 表示領域幅
	int height;	// 表示領域高さ
	Component component;	// コンポーネント
備考	引数なしのコンストラクタを呼んだときには、かならず Create() で初期化
	すること。

boolean	Create( pattern, plane, width, heightm, component );
	引数はコンストラクタに同じ
機能	スプライトコントロールクラスの初期化
戻り値	true	成功
	false	失敗
備考	コンストラクタで初期化した場合は、Create() を呼ぶ必要はない。

boolean	CreateBackground( int backgound, int width[], int height[],
	int num[] );
	int background;	// バックグラウンド枚数
	int width[];	// それぞれのバックグラウンドの幅を格納した配列
	int height[];	// それぞれのバックグラウンドの高さを格納した配列
	int num[];	// それぞれのバックグラウンドに設定できるスプライト
			// パターン数を格納した配列
機能	バックグラウンドの作成
戻り値	true	成功
	false	失敗

boolean	Define( pattern, image );
	int pattern;	// パターン番号
	Image image;	// パターンデータ
機能	パターンの定義
戻り値	true	成功
	false	失敗

boolean	Clear( plane );
	int plane;	// プレーン番号
機能	プレーンの初期化
戻り値	true	成功
	false	失敗
備考	構築時にはすでに初期化されている。

boolean	Show();
boolean	Show( int plane1, int plane2 );
	int plane1;	// 開始プレーン番号
	int plane2;	// 終了プレーン番号
機能	開始プレーンから終了プレーンまでの表示
戻り値	true	成功
	false	失敗
備考	引数を省略した場合は、全てのプレーンが対象になる。

boolean	Hide();
boolean	Hide( int plane1, int plane2 );
	int plane1;	// 開始プレーン番号
	int plane2;	// 終了プレーン番号
機能	開始プレーンから終了プレーンまでの非表示
戻り値	true	成功
	false	失敗
備考	引数を省略した場合は、全てのプレーンが対象になる。

boolean	Set( plane, pattern );
	int plane;	// プレーン番号
	int patten;	// パターン番号
機能	指定パターンの指定プレーンへの設定
戻り値	true	成功
	false	失敗

boolean	UserDraw( plane, width, height );
	int plane;	// プレーン番号
	int width;	// プレーンの幅
	int height;	// プレーンの高さ
機能	指定プレーンをユーザードロープレーンに設定
戻り値	true	成功
	false	失敗
備考	描画には SpriteEventHandler を implements し、
	SpriteEvent.SE_USERDRAWPLANE イベントをハンドルする。
	Set() と UserDraw() は排他。

boolean	Move( plane, x, y );
boolean Move( plane, x, y, pattern );
	int plane;	// プレーン番号
	int x;		// X座標
	int y;		// Y座標
	int pattern;	// パターン番号
機能	指定プレーンのスクロール値およびパターンの設定
戻り値	true	成功
	false	失敗
備考	パターン番号を省略した場合は、以前設定したパターンが有効となる。

boolean	BGShow();
boolean	BGShow( int bgplane1, int bgplane2 );
	int bgplane1;	// 開始バックグラウンドプレーン番号
	int bgplane2;	// 終了バックグラウンドプレーン番号
機能	開始バックグラウンドプレーンから終了バックグラウンドプレーンまでの
	表示
戻り値	true	成功
	false	失敗
備考	引数を省略した場合は、全てのバックグラウンドプレーンが対象になる。

boolean	BGHide();
boolean	BGHide( int plane1, int plane2 );
	int plane1;	// 開始バックグラウンドプレーン番号
	int plane2;	// 終了バックグラウンドプレーン番号
機能	開始バックグラウンドプレーンから終了バックグラウンドプレーンまでの
	非表示
戻り値	true	成功
	false	失敗
備考	引数を省略した場合は、全てのバックグラウンドプレーンが対象になる。

boolean	SetBGPattern( int bgplane, int num, int x, int y, int pattern );
boolean	SetBGPattern( int bgplane, int num, int pattern );
	int bgplane;	// バックグラウンドプレーン番号
	int num;	// バックグラウンドパターン番号
	int x;		// X座標
	int y;		// Y座標
	int pattern;	// パターン番号
機能	バックグラウンドのパターン設定
戻り値	true	成功
	false	失敗
備考	座標を省略した場合は、以前に設定した値が有効になる。パターン番号に
	-1を設定すると、クリアされます。

boolean	SetBGPriority( int bgplane, int priority );
	int bgplane;	// バックグラウンドプレーン番号
	int priority;	// プライオリティ
機能	バックグラウンドのプライオリティ設定
戻り値	true	成功
	false	失敗
備考	プライオリティで設定した値と同じスプライトプレーンの手前に表示する。
	ただし、バックグラウンドプレーン番号の小さいものほどプライオリティ
	番号も小さい値を設定する。

boolean	BGScroll( int bgplane, int x, int y );
	int bgplane;	// バックグラウンドプレーン番号
	int x;		// 表示位置のXオフセット
	int y;		// 表示位置のYオフセット
機能	バックグラウンドの表示位置を設定する
戻り値	true	成功
	false	失敗
備考	バックグラウンドは球面スクロールする。

void	Display( g, x, y, observer );
void	Display( g, observer );
	Graphics g;	// グラフィックコンテキスト
	int x;		// 表示位置のXオフセット
	int y;		// 表示位置のYオフセット
	ImageObserver observer;	// イメージオブザーバー
機能	スプライトの描画
備考	オフセットを省略した場合には、( 0, 0 )となる。

void	SetBGColor( color );
	Color color;	// 背景色
機能	背景色の設定
備考	デフォルトは背景色の設定なし(背景色塗り潰しを行わない)。null を設定
	することで、デフォルトに戻る。

void	SetClipMode( mode );
	boolean mode;	// クリップモード
機能	クリップモードの設定
備考	デフォルトはクリップモードOFF(全画面書き換え)。

void	SetBGImage( image );
	Image image;	// 背景イメージ
機能	背景イメージの設定
備考	デフォルトは背景イメージの設定なし。null を設定することで、デフォルト
	に戻る。

void	Draw( g, observer );
void	Draw( g, x, y, observer );
	Graphics g;	// グラフィックコンテキスト
	int x;		// 表示位置のXオフセット
	int y;		// 表示位置のYオフセット
	ImageObserver observer;	// イメージオブザーバー
機能	画面のリフレッシュ
備考	オフセットを省略した場合には、( 0, 0 )となる。

・SpriteCanvas クラス
 レイアウトをする場合に使用します。ユーザーメソッドは以下の通り。

コンストラクタ
SpriteCanvas();
SpriteCanvas( pattern, plane, width, height, component );
	int pattern;	// パターン確保数
	int plane;	// プレーン確保数
	int width;	// 表示領域幅
	int height;	// 表示領域高さ
	Component component;	// コンポーネント
備考	引数なしのコンストラクタを呼んだときには、かならず Create() で初期化
	すること。

boolean	Create( pattern, plane, width, heightm, component );
	引数はコンストラクタに同じ
機能	スプライトコントロールクラスの初期化
戻り値	true	成功
	false	失敗
備考	コンストラクタで初期化した場合は、Create() を呼ぶ必要はない。

boolean	CreateBackground( int backgound, int width[], int height[],
	int num[] );
	int background;	// バックグラウンド枚数
	int width[];	// それぞれのバックグラウンドの幅を格納した配列
	int height[];	// それぞれのバックグラウンドの高さを格納した配列
	int num[];	// それぞれのバックグラウンドに設定できるスプライト
			// パターン数を格納した配列
機能	バックグラウンドの作成
戻り値	true	成功
	false	失敗

void WaitLoadImage( tracker, id );
	MediaTracker tracker;	// メディアトラッカーのインスタンス
	int id;		// ID
機能	引数で渡されたメディアトラッカーの指定 ID のイメージがロードされるま
	で表示を行わず、"Loading..." の文字を表示します。

boolean	Define( pattern, image );
	int pattern;	// パターン番号
	Image image;	// パターンデータ
機能	パターンの定義
戻り値	true	成功
	false	失敗

boolean	Clear( plane );
	int plane;	// プレーン番号
機能	プレーンの初期化
戻り値	true	成功
	false	失敗
備考	構築時にはすでに初期化されている。

boolean	Show();
boolean	Show( int plane1, int plane2 );
	int plane1;	// 開始プレーン番号
	int plane2;	// 終了プレーン番号
機能	開始プレーンから終了プレーンまでの表示
戻り値	true	成功
	false	失敗
備考	引数を省略した場合は、全てのプレーンが対象になる。

boolean	Hide();
boolean	Hide( int plane1, int plane2 );
	int plane1;	// 開始プレーン番号
	int plane2;	// 終了プレーン番号
機能	開始プレーンから終了プレーンまでの非表示
戻り値	true	成功
	false	失敗
備考	引数を省略した場合は、全てのプレーンが対象になる。

boolean	Set( plane, pattern );
	int plane;	// プレーン番号
	int patten;	// パターン番号
機能	指定パターンの指定プレーンへの設定
戻り値	true	成功
	false	失敗

boolean	UserDraw( plane, width, height );
	int plane;	// プレーン番号
	int width;	// プレーンの幅
	int height;	// プレーンの高さ
機能	指定プレーンをユーザードロープレーンに設定
戻り値	true	成功
	false	失敗
備考	描画には SpriteEventHandler を implements し、
	SpriteEvent.SE_USERDRAWPLANE イベントをハンドルする。
	Set() と UserDraw() は排他。

boolean	Move( plane, x, y );
boolean Move( plane, x, y, pattern );
	int plane;	// プレーン番号
	int x;		// X座標
	int y;		// Y座標
	int pattern;	// パターン番号
機能	指定プレーンのスクロール値およびパターンの設定
戻り値	true	成功
	false	失敗
備考	パターン番号を省略した場合は、以前設定したパターンが有効となる。

boolean	BGShow();
boolean	BGShow( int bgplane1, int bgplane2 );
	int bgplane1;	// 開始バックグラウンドプレーン番号
	int bgplane2;	// 終了バックグラウンドプレーン番号
機能	開始バックグラウンドプレーンから終了バックグラウンドプレーンまでの
	表示
戻り値	true	成功
	false	失敗
備考	引数を省略した場合は、全てのバックグラウンドプレーンが対象になる。

boolean	BGHide();
boolean	BGHide( int plane1, int plane2 );
	int plane1;	// 開始バックグラウンドプレーン番号
	int plane2;	// 終了バックグラウンドプレーン番号
機能	開始バックグラウンドプレーンから終了バックグラウンドプレーンまでの
	非表示
戻り値	true	成功
	false	失敗
備考	引数を省略した場合は、全てのバックグラウンドプレーンが対象になる。

boolean	SetBGPattern( int bgplane, int num, int x, int y, int pattern );
boolean	SetBGPattern( int bgplane, int num, int pattern );
	int bgplane;	// バックグラウンドプレーン番号
	int num;	// バックグラウンドパターン番号
	int x;		// X座標
	int y;		// Y座標
	int pattern;	// パターン番号
機能	バックグラウンドのパターン設定
戻り値	true	成功
	false	失敗
備考	座標を省略した場合は、以前に設定した値が有効になる。パターン番号に
	-1を設定すると、クリアされます。

boolean	SetBGPriority( int bgplane, int priority );
	int bgplane;	// バックグラウンドプレーン番号
	int priority;	// プライオリティ
機能	バックグラウンドのプライオリティ設定
戻り値	true	成功
	false	失敗
備考	プライオリティで設定した値と同じスプライトプレーンの手前に表示する。
	ただし、バックグラウンドプレーン番号の小さいものほどプライオリティ
	番号も小さい値を設定する。

boolean	BGScroll( int bgplane, int x, int y );
	int bgplane;	// バックグラウンドプレーン番号
	int x;		// 表示位置のXオフセット
	int y;		// 表示位置のYオフセット
機能	バックグラウンドの表示位置を設定する
戻り値	true	成功
	false	失敗
備考	バックグラウンドは球面スクロールする。

void	Display( g );
	Graphics g;	// グラフィックコンテキスト
	Color bgcolor;	// 背景色
機能	スプライトの描画
備考	背景色を省略した場合は、背景は初期化されない。

void	SetBGImage( image );
	Image image;	// 背景イメージ
機能	背景イメージの設定
備考	デフォルトは背景イメージの設定なし。null を設定することで、デフォルト
	に戻る。

void	SetClipMode( mode );
	boolean mode;	// クリップモード
機能	クリップモードの設定
備考	デフォルトはクリップモードOFF(全画面書き換え)。

void	Draw();
機能	スプライトの更新
備考	スプライトの描画には、通常は Display() ではなく、こちらを使用する。

・SpriteEventHandler インターフェース
 スプライトイベントをハンドルする場合に、アプレットクラスに implements し、以下のメソッドを宣言します。

public boolean handleSpriteEvent( SpriteEvent se );
	SpriteEvent se;	// スプライトイベントクラスのインスタンス
機能	スプライトイベントのハンドル
備考	イベントを処理した場合は true を、しない場合は false を返す。

・SpriteEvent クラス
 スプライトイベントで渡されるクラスです。イベント ID でイベントを識別します。

メンバ変数

[入力]
int	id;	イベントID
int	no;
Graphics	g;

[出力]
Rectangle	rv_rc;
イベント ID
SpriteEvent.SE_DRAW
	スプライトが画面に描画される直前に呼ばれるイベント
備考	スプライト以外の物を重ねて描画する場合に処理する。入力 g はオフスク
	リーンコンテキストであり、描画を行った場合はその領域を出力 rv_rc で
	返す。

SpriteEvent.SE_USERDRAWPLANE
	ユーザードロープレーンが描画される必要がある時に呼ばれるイベント
備考	SpriteControl.UseDraw() あるいは SpriteCanvas.UserDraw() によって設
	定されたユーザードロープレーンの描画時に処理する。入力 no はプレーン
	番号であり、g に対して描画を行う。

◇ プログラム例
・SpriteControl クラスを使った場合
import java.applet.Applet;
import java.awt.*;

public class foo extends Applet implements Runnable {
	boolean up, down, left, right;
	int x, y;
	SpriteControl sc;
	MediaTracker mt;
	Thread thread=null;
	void init(){
		Image image;
		// スプライトにするイメージを読み込む
		image = getImage( getDocumentBase(), "foo.gif" );
		// メディアトラッカーで読み込み監視
		mt = new MediaTracker( this );
		mt.addImage( image, 0 );
		// スプライトコントロールクラスのインスタンスを作成する。
		// ここで初期化してもよい。
		sc = new SpriteControl();
		// 初期化
		sc.Create( ptmax, plmax, size().width, size().height, this );
		// 読み込んだイメージをパターン0に登録
		sc.Define( 0, image );
		// パターン0のデータをプレーン0に設定
		sc.Set( 0, 0 );
		// プレーン0を表示
		sc.Show( 0, 0 );
		// キーは押されていない
		up = down = left = right = false;
	}
	// update() を上書きして、書き換え時のちらつきを防ぐ
	public void update( Graphics g ){
		paint( g );
	}
	public void paint( Graphics g ){
		// イメージのロードは済んだか?
		if( mt.checkID( 0 ) ){
			// スプライト描画
			sc.Display( g, x0, y0, this );
		} else {
			// ロード中
			g.drawString( "Loading...", 0, 12 );
		}
	}
	// この辺はマルチスレッドアプレットの常套手段
	public void start(){
		if( thread==null ){
			thread = new Thread( this );
			thread.start();
		}
	}
	public void stop(){
		if( thread!=null ){
			thread.stop();
			thread = null;
		}
	}
	// バックグラウンドスレッド
	public void run(){
		try {
			// イメージロードを待つ
			mt.waitForID( 0 );
		} catch( InterruptedException e ){
			return;
		}
		while( true ){
			try {
				// waitミリ秒間隔で目覚める
				Thread.sleep( wait );
			} catch( InterruptedException e ){
				break;
			}
			// キーが押されたか調べる。
			// 本当はクリッピング処理なども必要
			if( up ){
				// ↑キーが押された時の処理
				y -= dy;
			}
			if( down ){
				// ↓
				y += dy;
			}
			if( left ){
				// ←
				x -= dx;
			}
			if( right ){
				// →
				x += dx;
			}
			// プレーン0のスクロール値をセット
			sc.Move( 0, x, y );
			// 再描画
			repaint();
		}
	}
	public boolean keyDown( Event e, int key ){
		switch( key ){
		case 1004:// ↑
			up = true;
			break;
		case 1005:// ↓
			down = true;
			break;
		case 1006:// ←
			left = true;
			break;
		case 1007:// →
			right = true;
			break;
		}
		return true;
	}
	public boolean keyUp( Event e, int key ){
		switch( key ){
		case 1004:// ↑
			up = false;
			break;
		case 1005:// ↓
			down = false;
			break;
		case 1006:// ←
			left = false;
			break;
		case 1007:// →
			right = false;
			break;
		}
		return true;
	}
}

・SpriteCanvas クラスを使った場合
import java.applet.Applet;
import java.awt.*;

public class foo extends Applet implements Runnable {
	boolean up, down, left, right;
	int x, y;
	SpriteCanvas sc;
	MediaTracker mt;
	Thread thread=null;
	void init(){
		Image image;
		// スプライトにするイメージを読み込む
		image = getImage( getDocumentBase(), "foo.gif" );
		// メディアトラッカーで読み込み監視
		mt = new MediaTracker( this );
		mt.addImage( image, 0 );
		// スプライトキャンバスクラスのインスタンスの作成と
		// 初期化
		sc = new SpriteCanvas( ptmax, plmax, width, height, this );
		// 適当にレイアウトする
		setLayout( new BorderLayout() );
		add( "Center", sc );
		add( "South", new Button( "Start" ) );
		// イメージのロードが終わるまで表示を止める
		sc.WaitLoadImage( mt, 0 );
		// 読み込んだイメージをパターン0に登録
		sc.Define( 0, image );
		// パターン0のデータをプレーン0に設定
		sc.Set( 0, 0 );
		// プレーン0を表示
		sc.Show( 0, 0 );
		// キーは押されていない
		up = down = left = right = false;
	}
	// この辺はマルチスレッドアプレットの常套手段
	public void start(){
		if( thread==null ){
			thread = new Thread( this );
			thread.start();
		}
	}
	public void stop(){
		if( thread!=null ){
			thread.stop();
			thread = null;
		}
	}
	// バックグラウンドスレッド
	public void run(){
		try {
			// イメージロードを待つ
			mt.waitForID( 0 );
		} catch( InterruptedException e ){
			return;
		}
		while( true ){
			try {
				// waitミリ秒間隔で目覚める
				Thread.sleep( wait );
			} catch( InterruptedException e ){
				break;
			}
			// キーが押されたか調べる。
			// 本当はクリッピング処理なども必要
			if( up ){
				// ↑キーが押された時の処理
				y -= dy;
			}
			if( down ){
				// ↓
				y += dy;
			}
			if( left ){
				// ←
				x -= dx;
			}
			if( right ){
				// →
				x += dx;
			}
			// プレーン0のスクロール値をセット
			sc.Move( 0, x, y );
			// スプライト更新
			sc.Draw();
		}
	}
	public boolean keyDown( Event e, int key ){
		switch( key ){
		case 1004:// ↑
			up = true;
			break;
		case 1005:// ↓
			down = true;
			break;
		case 1006:// ←
			left = true;
			break;
		case 1007:// →
			right = true;
			break;
		}
		return true;
	}
	public boolean keyUp( Event e, int key ){
		switch( key ){
		case 1004:// ↑
			up = false;
			break;
		case 1005:// ↓
			down = false;
			break;
		case 1006:// ←
			left = false;
			break;
		case 1007:// →
			right = false;
			break;
		}
		return true;
	}
}

・スプライトイベントをハンドルする場合
import java.applet.Applet;
import java.awt.*;

public class foo extends Applet implements Runnable, SpriteEventHandler {
	int x, y, width, height;
	int score;
		 :
		中略
		 :
	public boolean handleSpriteEvent( SpriteEvent se ){
		switch( se.id ){
		case se.SE_DRAW:
			se.g.drawString( "SCORE "+score, x, y );
			se.rv_rc = new Rectangle( x, y-height, width, height );
			break;
		default:
			return false;
		}
		return true;
	}
}

 付属のサンプル ShootSaucer は、SpriteCanvas を使っています。

 バックグラウンドの使用法については、付属のサンプル scroll を参考にしてください。

◇ クリッピングモードについて
 クリッピングモードが OFF の場合は、スプライトの更新は全画面書き換えされます。Java はペイントイベントが連続して行われた場合キューイングしますが、実際には最後にキューイングされた領域しかペイントしません。そのため、キャラクタが多い場合などは、正しくペイントされずにゴミが出ます。そのような場合、あるいは背景をスクロールさせて結果的に全画面書き換えになる場合には、こちらの方が有効になります。モードの切り替えはリアルタイムで有効ですので、その場その場で使い分けることも可能です。また、バックグラウンドを使用すると、自動的にクリッピングモードは OFF になります。

◇ コンパイルについて
 コンパイル時には CLASSPATH またはオプションで SpriteLib.jar を指定してください。

ex. スプライトマネージャを使った foo.java をコンパイルする場合
> javac -classpath SpriteLib.jar foo.java

◇ HTML での表記
 作成したアプレットを表示するには、archive として SpriteLib.jar を指定してください。

ex. スプライトマネージャを使った foo.class を表示する場合
<applet code="foo.class" archive="SpriteLib.jar"></applet>

◇ 著作権
 この Java 擬似スプライトマネージャおよびデモゲーム ShootSaucer は、フリーウェアで、著作権は菊地功が保有しています。このマネージャは、以下の条件を満たす場合に限り、頒布・転載を認めます。

・アーカイブの内容を変更しないこと
・実費以上の金銭の授受がなきこと
・商業的目的での頒布時には、あらかじめ著作者に連絡し、許可をとること

 また、このマネージャを使用して制作されたアプレットの公開時には、スプライトマネージャ使用の旨を明記してください。

◇ 連絡先
 何かありましたら、下記までお願いします。質問、要望、バグ情報など何でもお待ちしています。

E-mailkisawo@hinix.com
WebPageうぃんどうぷろしーじゃ

◇ 更新履歴
2000/8/1version 0.40イベントハンドラを追加。
1997/2/12version 0.35安易な方法でバックグラウンドを付けた。動作自体はこっちの方が正しいんだけどね。
1997/2/9version 0.32バグフィックス。バックグラウンドを付けようとしたが失敗。なんでAlphaがいじれない?
1996/6/6version 0.31バグフィックス。正式公開版。
1996/5/29version 0.30クリッピングモードを追加。それに伴う各部の修正。
1996/5/17version 0.20SpriteCanvasクラスを追加。
1996/5/16version 0.11Move()メソッドでパターン番号を設定できるようにした。
1996/5/15 version 0.10